package com.example.multinetty.netty.secondprotocal;

import com.alibaba.fastjson.JSONObject;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.DefaultFullHttpRequest;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpVersion;

import java.io.IOException;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class ByteToFullRequestDecoder extends ChannelInboundHandlerAdapter {
    CompositeFullHttp compositeFullHttp=new CompositeFullHttp();
    MarshallingDecoder marshallingDecoder;

    public ByteToFullRequestDecoder() throws IOException, Exception {
        //super(maxFrameLength, lengthFieldOffset, lengthFieldLength);
        marshallingDecoder = new MarshallingDecoder();
    }
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        ByteBuf content=(ByteBuf) msg;
        Charset charset=Charset.defaultCharset();
        String input=content.toString(charset);

        URI uri=new URI("/llflogin");//实际上需要从协议包中获取
        FullHttpRequest fullHttpRequest=new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST,uri.toASCIIString());
        fullHttpRequest.content().readBytes(content);

        NettyMessage nettyMessage= parseByteBufToNettyMessage(content);
        try {
            //ByteBuf buf=fullHttpRequest.content();
            int readable=content.readableBytes();
            byte[] bytes=new byte[readable];
            content.readBytes(bytes);
            compositeFullHttp.setFullHttpRequest(fullHttpRequest);
            String json=JSONObject.toJSONString(nettyMessage);
            compositeFullHttp.setContents(json.getBytes(StandardCharsets.UTF_8));
            //为什么要将NettyMessage转为byte[]，发给下一个环节，而不是直接转给FullHttpRequest
            //答：fullhttpRequest的content是ByteBuf的属性，而不是byte[]的属性。
            //在这个环节，解析为一个类，主要的目的，是填写defaultFullhttprequest。实际上，感觉转http的可以放在下一个环节。本环节，仅仅是处理到一个实体类的过程。不涉及到http的任何内容
            /*
            String contentStr= UriUtils.decode(new String(bytes,"UTF-8"),"UTF-8");*/
            //System.out.println("http post请求写入数据:"+contentStr);
            //fullHttpRequest.content().release();
        }catch (Exception ex){

        }
        content.release();
        //ByteBuf byteBuf= fullHttpRequest.content();

        //channelHandlerContext.write(fullHttpRequest);
        ctx.fireChannelRead(compositeFullHttp);
    }

    private NettyMessage parseByteBufToNettyMessage(ByteBuf frame) throws Exception{
        NettyMessage message = new NettyMessage();
        Header header = new Header();
        header.setCrcCode(frame.readInt());
		header.setLength(frame.readInt());
		header.setSessionID(frame.readLong());
		header.setType(frame.readByte());
		header.setPriority(frame.readByte());

		int size = frame.readInt();
		if (size > 0) {
			Map<String, Object> attch = new HashMap<String, Object>(size);
			int keySize = 0;
			byte[] keyArray = null;
			String key = null;
			for (int i = 0; i < size; i++) {
				keySize = frame.readInt();
				keyArray = new byte[keySize];
				frame.readBytes(keyArray);
				key = new String(keyArray, "UTF-8");
				attch.put(key, marshallingDecoder.decode(frame));
			}
			keyArray = null;
			key = null;
			header.setAttachment(attch);
		}
		if (frame.readableBytes() > 4) {//说明后面还有第二个附件或者是body，需要继续反序列化读出来
			message.setBody(marshallingDecoder.decode(frame));
		}
		message.setHeader(header);
        return message;
    }
}
